package com.ews.onlineexchange.model;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.PostLoad;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;

import com.ews.onlineexchange.util.SystemUUIDUtil;

@Entity
public class QualificationGroup extends DataEntity {

	/** 
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Bulletin bulletin;
	private List<QualificationTemplate>	qualificationTemplates = new ArrayList<QualificationTemplate>();
	
	private  Relation relation;//组内template关系（全部符合，符合其中一个）
	
	private QualificationGroup parentGroup;
	
	private RequireType requireType = RequireType.QualificationRequirement ;
	private List<QualificationGroup> groups = new ArrayList<>();
	
	private List<AgentService> agentServices = new ArrayList<AgentService>();
	
	private String groupIndex;
	
	
	@OneToOne
	public Bulletin getBulletin() {
		return bulletin;
	}

	public void setBulletin(Bulletin bulletin) {
		this.bulletin = bulletin;
	}

	@Transient
	public String getGroupIndex() {
		return groupIndex;
	}

	public void setGroupIndex(String groupIndex) {
		this.groupIndex = groupIndex;
	}

	@NotNull
	@Enumerated(EnumType.STRING)
	public Relation getRelation() {
		return relation;
	}

	public void setRelation(Relation relation) {
		this.relation = relation;
	}
	
	
	@NotNull
	@Enumerated(EnumType.STRING)
	public RequireType getRequireType() {
		return requireType;
	}

	public void setRequireType(RequireType requireType) {
		this.requireType = requireType;
	}

	@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})	
	@JoinTable(name = "GROUP_TEMPLATES")
	public List<QualificationTemplate> getQualificationTemplates() {
		return qualificationTemplates;
	}

	public void setQualificationTemplates(List<QualificationTemplate> qualificationTemplates) {
		this.qualificationTemplates = qualificationTemplates;
	}	
	
	@ManyToMany	
	@JoinTable(name = "GROUP_AGENTSERVICE")
	public List<AgentService> getAgentServices() {
		return agentServices;
	}

	public void setAgentServices(List<AgentService> agentServices) {
		this.agentServices = agentServices;
	}

	@ManyToOne
	public QualificationGroup getParentGroup() {
		return parentGroup;
	}

	public void setParentGroup(QualificationGroup parentGroup) {
		this.parentGroup = parentGroup;
	}
	
	@OneToMany(mappedBy = "parentGroup", cascade = CascadeType.ALL)
	@OrderBy("sort")
	public List<QualificationGroup> getGroups() {
		return groups;
	}

	public void setGroups(List<QualificationGroup> groups) {
		this.groups = groups;
	}
	
	@Transient
	public void addEmptyQualificationTemplate() {
		this.getQualificationTemplates().add(new QualificationTemplate());
	}
	
	@Transient
	public void removeQualificationTemplate(int index) {
		this.getQualificationTemplates().remove(index);
	}
	
	@Transient
	public void addEmptyAgentService() {
		this.getAgentServices().add(new AgentService());
	}
	@Transient
	public void removeAgentService(int index) {
		this.getAgentServices().remove(index);
	}
	@Transient
	public String getQualificationGroupDetail() {
		StringBuilder sb = new StringBuilder();
		for (QualificationGroup qualificationGroup : getQualificationGroups()) {
			sb.append("[");
				List<QualificationTemplate> templates = qualificationGroup.getQualificationTemplates();
				for (QualificationTemplate qualificationTemplate : templates) {
						sb.append(qualificationTemplate.getDetail());
						if(qualificationGroup.relation.equals(Relation.And)) {
							sb.append("和");
						}else {
							sb.append("或");
						}
				}
				if (sb.length() > 0)
				sb = new StringBuilder(sb.substring(0, sb.length() - 1));
				sb.append("]");
				if(getRelation().equals(Relation.And)) {
					sb.append("和");
				}else {
					sb.append("或");
				}
				
		}
		
		if (sb.length() == 0)
			return "";
		return sb.substring(0, sb.length() - 1);
	}		
	
	
	
	@Transient
	public List<QualificationGroup> getAgentServiceGroupsFromRootGroup(){
		List<QualificationGroup> agentServiceGroups = new ArrayList<>();
//		if(getQualificationGroup()  == null ) return null;
		for (QualificationGroup qualificationGroup : getGroups()) {
			if(qualificationGroup.getRequireType().equals(RequireType.AgentServiceRequirement)) {
				qualificationGroup.setGroupIndex(SystemUUIDUtil.getUUID());
				agentServiceGroups.add(qualificationGroup);
			}
		}
		return agentServiceGroups;
		
	}
	
	@Transient
	public List<QualificationGroup> getQualificationGroupsFromRootGroup(){
		List<QualificationGroup> qualificationGroups = new ArrayList<>();
//		if(getQualificationGroup()  == null ) return null;
		for (QualificationGroup qualificationGroup : getGroups()) {
			if(qualificationGroup.getRequireType().equals(RequireType.QualificationRequirement)) {
				qualificationGroup.setGroupIndex(SystemUUIDUtil.getUUID());
				qualificationGroups.add(qualificationGroup);
			}
		}
		return qualificationGroups;
		
	}	
	 
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + ((bulletin == null) ? 0 : bulletin.hashCode());
		result = prime * result + ((parentGroup == null) ? 0 : parentGroup.hashCode());
		result = prime * result + ((relation == null) ? 0 : relation.hashCode());
		result = prime * result + ((requireType == null) ? 0 : requireType.hashCode());
		return result;
	}

	@Override
	public boolean equals( Object obj ) {
		if ( this == obj )
			return true;
		if ( !super.equals( obj ) )
			return false;
		if ( getClass() != obj.getClass() )
			return false;
		QualificationGroup other = (QualificationGroup) obj;
		if ( bulletin == null ) {
			if ( other.bulletin != null )
				return false;
		} else if ( !bulletin.equals( other.bulletin ) )
			return false;
		if ( parentGroup == null ) {
			if ( other.parentGroup != null )
				return false;
		} else if ( !parentGroup.equals( other.parentGroup ) )
			return false;
		if ( relation != other.relation )
			return false;
		if ( requireType != other.requireType )
			return false;
		return true;
	}

	private List<QualificationGroup> agentServiceGroups = new ArrayList<>();

	private List<QualificationGroup> qualificationGroups = new ArrayList<>();
	
	@Transient
	public List<QualificationGroup> getAgentServiceGroups() {
		return agentServiceGroups;
	}

	public void setAgentServiceGroups(List<QualificationGroup> agentServiceGroups) {
		this.agentServiceGroups = agentServiceGroups;
	}
	@Transient 
	public List<QualificationGroup> getQualificationGroups() {
		return qualificationGroups;
	}

	public void setQualificationGroups(List<QualificationGroup> qualificationGroups) {
		this.qualificationGroups = qualificationGroups;
	}
	
	public void initSubGroups() {
		setAgentServiceGroups(getAgentServiceGroupsFromRootGroup());
		setQualificationGroups(getQualificationGroupsFromRootGroup());
	}
	
}
